#include <iostream>
#include <string>
#include <memory>

class Computer
{
public:
    void setBoard(const std::string& board)       // 派生类不重写，不要加virtual
    {
        _board = board;             // 没加virtual，需要对成员变量进行赋值
    }
    void setDisplay(const std::string& display)
    {
        _display = display;
    }
    virtual void setOs() = 0;

    // void show()
    std::string show()
    {
        // std::cout<<_board<<" "<<_display<<std::endl;
        std::string comp = "computer:\n ";          // 换行之和多加一个空格，否则下一句中文可能乱码
        comp += "\tboard: " + _board + " \n ";
        comp += "\tdisplay: " + _display + "\n ";
        comp += "\tos: " + _os + "\n";
        // std::cout << comp << std::endl;
        return comp;
    }
protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

class Legion : public Computer
{
public:
    void setOs()
    {
        _os = "Windows 11";
    }
};

class Builder
{
public:
    virtual void buildBoard(const std::string& board) = 0;
    virtual void buildDisplay(const std::string& display) = 0;
    virtual void buildOs() = 0;     // os也需要调用
    virtual std::shared_ptr<Computer> build() = 0;
};

class LegionBuilder : public Builder
{
public:
    LegionBuilder():_cp(new Legion()){}         // 构造对象
    void buildBoard(const std::string& board)
    {
        _cp->setBoard(board);
    }

    void buildDisplay(const std::string& display)
    {
        _cp->setDisplay(display);
    }

    void buildOs()
    {
        _cp->setOs();
    }

    std::shared_ptr<Computer> build()
    {
        return _cp;
    }

private:
    std::shared_ptr<Computer> _cp;        // 类型需要是Computer
};

class Direct
{
public:
    Direct(Builder* bp):_bp(bp){}

    void construct(const std::string& board, const std::string& display)
    {
        _bp->buildBoard(board);
        _bp->buildDisplay(display);
        _bp->buildOs();
    }
private:
    std::shared_ptr<Builder> _bp;
};

int main()
{
    Builder* bp = new LegionBuilder();
    std::unique_ptr<Direct> dup(new Direct(bp));
    dup->construct("联想", "三星");
    std::shared_ptr<Computer> cp = bp->build();
    std::cout << cp->show();
    // cp->show();

    return 0;
}